package org.vellos.halide.vm;

import org.vellos.halide.vm.Math.BasicMath;
import java.util.HashMap;
import java.util.Map;
import org.vellos.halide.parse.ExpressionNode;
import org.vellos.halide.parse.Parser;

public class VirtualMachine {

  Map<String, Object> variables;

  public VirtualMachine() {
    this.variables = new HashMap<String, Object>();
  }

  public String evaluateNode(ExpressionNode en) throws Exception {
    String operator = (String) en.getNodes().get(0);

    if(operator.equals("+")) return BasicMath.add(en);
    if(operator.equals("-")) return BasicMath.subtract(en);
    if(operator.equals("*")) return BasicMath.multiply(en);
    if(operator.equals("/")) return BasicMath.divide(en);
    if(operator.equals("defparameter")) return BasicOperators.defparameter(en, this);

    Object var;
    if ((var = getVariable(operator)) != null) {
      try {
        // Can it be turned into an expression?
        return evaluateNode(new Parser().parseExpression((String) var));
      } catch (Exception e) {
        // A variable perhapsS?  Just return it.
        return (String) var;
      }
    }

    throw new OperatorUnknownException(operator);
  }

  Object getVariable(String varName) {
    return variables.get(varName);
  }

  void setVariable(String varName, Object value) {
    variables.put(varName, value);
  }
}
